using System;
using System.Collections.Generic;
using System.Text;

namespace Workflows.Components.Reports
{
    public class ColumnChartRdlGenerator
    {
        private ChartReportItem _ChartItem;
        public ChartReportItem ChartItem
        {
            get
            {
                return this._ChartItem;
            }
            set
            {
                this._ChartItem = value;
            }
        }

        public ChartType GenerateColumnChart()
        {
            ChartType chart = new ChartType();
            chart.Name = "Chart_" + this._ChartItem.Id.ToString();

            chart.Items = new object[]{
                this.CreateChartThreeDProperties(), 
                this.CreateChartStyle(), 
                this.CreateChartLegend(), 
                this.CreateChartPalette(), 
                this.CreateChartData(), 
                this.CreateChartCategoryAxis(), 
                "DataSet_" + this._ChartItem.Id.ToString(), 
                this.CreateChartPointWidth(),
                this.CreateChartType(), 
                this.CreateChartTitle(), 
                this.CreateChartCategoryGroupings(), 
                this.CreateChartSeriesGroupings(), 
                this.CreateChartSubType(), 
                this.CreateChartPlotArea(), 
                this.CreateChartValueAxis()};
            chart.ItemsElementName = new ItemsChoiceType27[]{
                ItemsChoiceType27.ThreeDProperties,
                ItemsChoiceType27.Style,
                ItemsChoiceType27.Legend,
                ItemsChoiceType27.Palette,
                ItemsChoiceType27.ChartData,
                ItemsChoiceType27.CategoryAxis,
                ItemsChoiceType27.DataSetName,
                ItemsChoiceType27.PointWidth,
                ItemsChoiceType27.Type,
                ItemsChoiceType27.Title,
                ItemsChoiceType27.CategoryGroupings,
                ItemsChoiceType27.SeriesGroupings,
                ItemsChoiceType27.Subtype,
                ItemsChoiceType27.PlotArea,
                ItemsChoiceType27.ValueAxis};

            return chart;
        }

        #region generation 
        private ThreeDPropertiesType CreateChartThreeDProperties()
        {
            ThreeDPropertiesType threeDProps = new ThreeDPropertiesType();
            threeDProps.Items = new object[]{
                "30",
                "30",
                this.CreateChartThreeDShading(),
                this.CreateChartThreeDWallThickness()};
            threeDProps.ItemsElementName = new ItemsChoiceType26[]{
                ItemsChoiceType26.Rotation,
                ItemsChoiceType26.Inclination,
                ItemsChoiceType26.Shading,
                ItemsChoiceType26.WallThickness};
            return threeDProps;
        }

        private ThreeDPropertiesTypeShading CreateChartThreeDShading()
        {
            return ThreeDPropertiesTypeShading.Simple;
        }

        private uint CreateChartThreeDWallThickness()
        {
            return 50;
        }

        private StyleType CreateChartStyle()
        {
            StyleType style = new StyleType();
            style.Items = new object[]{
                "White",
                this.CreateChartBorderStyle()};
            style.ItemsElementName = new ItemsChoiceType5[]{
                ItemsChoiceType5.BackgroundColor,
                ItemsChoiceType5.BorderStyle};
            return style;
        }

        private BorderColorStyleWidthType CreateChartBorderStyle()
        {
            BorderColorStyleWidthType borderType = new BorderColorStyleWidthType();
            borderType.Items = new object[] { "Solid" };
            borderType.ItemsElementName = new ItemsChoiceType3[]{
                ItemsChoiceType3.Default};
            return borderType;
        }

        private LegendType CreateChartLegend()
        {
            return new LegendType();
        }

        private ChartTypePalette CreateChartPalette()
        {
            return ChartTypePalette.Default;
        }

        private ChartTypeType CreateChartType()
        {
            return ChartTypeType.Column;
        }

        private TitleType CreateChartTitle()
        {
            return new TitleType();
        }

        private ChartTypeSubtype CreateChartSubType()
        {
            return ChartTypeSubtype.Plain;
        }

        private ChartDataType CreateChartData()
        {
            ChartDataType chartData = new ChartDataType();
            chartData.ChartSeries = new ChartSeriesType[this._ChartItem.ChartData.SeriesCollection.Count];
            for (int i = 0; i < this._ChartItem.ChartData.SeriesCollection.Count; i++)
            {
                chartData.ChartSeries[i] = this.CreateChartSeries();
            }
            return chartData;
        }

        private ChartSeriesType CreateChartSeries()
        {
            ChartSeriesType chartSeries = new ChartSeriesType();
            chartSeries.Items = new object[] { this.CreateChartDataPoints() };
            return chartSeries;
        }

        private DataPointsType CreateChartDataPoints()
        {
            DataPointsType dataPoints = new DataPointsType();
            dataPoints.DataPoint = new DataPointType[] { this.CreateChartDataPoint() };
            return dataPoints;
        }

        private DataPointType CreateChartDataPoint()
        {
            DataPointType dataPoint = new DataPointType();
            dataPoint.Items = new object[] { 
                this.CreateChartDataValues(), 
                this.CreateChartDataLabel(), 
                this.CreateChartMarker()};
            return dataPoint;
        }

        private DataValuesType CreateChartDataValues()
        {
            DataValuesType dataValues = new DataValuesType();
            dataValues.DataValue = new DataValueType[] { this.CreateChartDataValue("Count") };
            return dataValues;
        }

        private DataValueType CreateChartDataValue(string fieldName)
        {
            DataValueType dataValue = new DataValueType();
            dataValue.Items = new object[]{
                "=Sum(Fields!"+fieldName+".Value)"};
            dataValue.ItemsElementName = new ItemsChoiceType22[]{
                ItemsChoiceType22.Value};
            return dataValue;
        }

        private DataLabelType CreateChartDataLabel()
        {
            return new DataLabelType();
        }

        private MarkerType CreateChartMarker()
        {
            MarkerType marker = new MarkerType();
            marker.Items = new object[] { "6pt" };
            return marker;
        }

        private CategoryAxisType CreateChartCategoryAxis()
        {
            CategoryAxisType categoryAxis = new CategoryAxisType();
            categoryAxis.Items = new object[] { this.CreateChartAxisX() };
            return categoryAxis;
        }

        private AxisType CreateChartAxisX()
        {
            AxisType axis = new AxisType();
            axis.Items = new object[]{
                this.CreateChartAxisXTitle(),
                this.CreateChartAxisXMajorGridLines(),
                this.CreateChartAxisXMinorGridLines(),
                this.CreateChartAxisXMajorTickMarks(),
                "0",
                true };
            axis.ItemsElementName = new ItemsChoiceType25[]{
                ItemsChoiceType25.Title,
                ItemsChoiceType25.MajorGridLines,
                ItemsChoiceType25.MinorGridLines,
                ItemsChoiceType25.MajorTickMarks,
                ItemsChoiceType25.Min,
                ItemsChoiceType25.Visible};
            return axis;
        }

        private TitleType CreateChartAxisXTitle()
        {
            TitleType title = new TitleType();
            return title;
        }

        private MajorGridLinesType CreateChartAxisXMajorGridLines()
        {
            return new MajorGridLinesType();
        }

        private MinorGridLinesType CreateChartAxisXMinorGridLines()
        {
            return new MinorGridLinesType();
        }

        private AxisTypeMajorTickMarks CreateChartAxisXMajorTickMarks()
        {
            return AxisTypeMajorTickMarks.Outside;
        }

        private uint CreateChartPointWidth()
        {
            return 0;
        }

        private CategoryGroupingsType CreateChartCategoryGroupings()
        {
            CategoryGroupingsType categoryGroupings = new CategoryGroupingsType();
            categoryGroupings.CategoryGrouping = new CategoryGroupingType[] { this.CreateChartCategoryGrouping() };
            return categoryGroupings;
        }

        private CategoryGroupingType CreateChartCategoryGrouping()
        {
            CategoryGroupingType categoryGrouping = new CategoryGroupingType();
            categoryGrouping.Items = new object[]{
                this.CreateChartDynamicCategories()};
            return categoryGrouping;
        }

        private DynamicCategoriesType CreateChartDynamicCategories()
        {
            DynamicCategoriesType dynamicCategories = new DynamicCategoriesType();
            dynamicCategories.Items = new object[]{
                this.CreateChartGrouping(),
                ""};
            return dynamicCategories;
        }

        private GroupingType CreateChartGrouping()
        {
            GroupingType grouping = new GroupingType();
            grouping.Name = "Chart_" + this._ChartItem.Id.ToString() + "_Group1";
            grouping.Items = new object[]{
                this.CreateChartGroupExpressions()};
            grouping.ItemsElementName = new ItemsChoiceType17[]{
                ItemsChoiceType17.GroupExpressions};
            return grouping;
        }

        private GroupExpressionsType CreateChartGroupExpressions()
        {
            GroupExpressionsType groupExpressions = new GroupExpressionsType();
            groupExpressions.GroupExpression = new string[this._ChartItem.ChartData.Categories.Count];
            for (int i = 0; i < this._ChartItem.ChartData.Categories.Count; i++)
            {
                groupExpressions.GroupExpression[i] = "=Fields!" + this._ChartItem.ChartData.Categories[i].Name + ".Value";
            }
            return groupExpressions;
        }

        private SeriesGroupingsType CreateChartSeriesGroupings()
        {
            SeriesGroupingsType seriesGroupings = new SeriesGroupingsType();
            seriesGroupings.SeriesGrouping = new SeriesGroupingType[]{
                this.CreateChartSeriesGrouping()};
            return seriesGroupings;
        }

        private SeriesGroupingType CreateChartSeriesGrouping()
        {
            SeriesGroupingType seriesGrouping = new SeriesGroupingType();
            if (this._ChartItem.ChartData.SeriesCollection.Count > 1)
            {
                seriesGrouping.Items = new object[]{
                    this.CreateChartDynamicSeries()};
            }
            else
            {
                seriesGrouping.Items = new object[]{
                    this.CreateChartStaticSeries()};
            }
            return seriesGrouping;
        }

        private DynamicSeriesType CreateChartDynamicSeries()
        {
            DynamicSeriesType dynamicSeries = new DynamicSeriesType();
            dynamicSeries.Items = new object[]{
                this.CreateChartGrouping2(), 
                "" };
            return dynamicSeries;
        }

        private GroupingType CreateChartGrouping2()
        {
            GroupingType grouping = new GroupingType();
            grouping.Name = "Chart_" + this._ChartItem.Id.ToString() + "_Grouping1";
            grouping.Items = new object[]{
                this.CreateChartGroupExpressions2()};
            grouping.ItemsElementName = new ItemsChoiceType17[]{
                ItemsChoiceType17.GroupExpressions};
            return grouping;
        }

        private GroupExpressionsType CreateChartGroupExpressions2()
        {
            GroupExpressionsType groupExpressions = new GroupExpressionsType();
            groupExpressions.GroupExpression = new string[]{
                ""};
            return groupExpressions;
        }

        private StaticSeriesType CreateChartStaticSeries()
        {
            StaticSeriesType staticSeries = new StaticSeriesType();
            staticSeries.StaticMember = new StaticMemberType[] { this.CreateChartStaticMemberType() };
            return staticSeries;
        }

        private StaticMemberType CreateChartStaticMemberType()
        {
            StaticMemberType staticMember = new StaticMemberType();
            staticMember.Items = new object[] { "Count" };
            return staticMember;
        }

        private PlotAreaType CreateChartPlotArea()
        {
            PlotAreaType plotArea = new PlotAreaType();
            plotArea.Items = new object[]{
                this.CreateChartPlotAreaStyle()};
            return plotArea;
        }

        private StyleType CreateChartPlotAreaStyle()
        {
            StyleType style = new StyleType();
            style.Items = new object[]{
                "LightGrey",
                this.CreateChartPlotAreaBorderStyle()};
            style.ItemsElementName = new ItemsChoiceType5[]{
                ItemsChoiceType5.BackgroundColor, 
                ItemsChoiceType5.BorderStyle};
            return style;
        }

        private BorderColorStyleWidthType CreateChartPlotAreaBorderStyle()
        {
            BorderColorStyleWidthType borderStyle = new BorderColorStyleWidthType();
            borderStyle.Items = new object[]{
                "Solid"};
            borderStyle.ItemsElementName = new ItemsChoiceType3[]{
                ItemsChoiceType3.Default};
            return borderStyle;
        }

        private ValueAxisType CreateChartValueAxis()
        {
            ValueAxisType valueAxis = new ValueAxisType();
            valueAxis.Items = new object[]{
                this.CreateChartAxisY()};
            return valueAxis;
        }

        private AxisType CreateChartAxisY()
        {
            AxisType axis = new AxisType();
            axis.Items = new object[] { 
                this.CreateChartAxisYTitle(),
                this.CreateChartAxisYStyle(), 
                this.CreateChartAxisYMajorGridLines(), 
                this.CreateChartAxisYMinorGridLines(), 
                this.CreateChartAxisYMajorTickMarks(), 
                "0", 
                true, 
                true, 
                true};
            axis.ItemsElementName = new ItemsChoiceType25[]{
                ItemsChoiceType25.Title,
                ItemsChoiceType25.Style,
                ItemsChoiceType25.MajorGridLines,
                ItemsChoiceType25.MinorGridLines,
                ItemsChoiceType25.MajorTickMarks,
                ItemsChoiceType25.Min,
                ItemsChoiceType25.Margin,
                ItemsChoiceType25.Visible,
                ItemsChoiceType25.Scalar};
            return axis;
        }

        private TitleType CreateChartAxisYTitle()
        {
            return new TitleType();
        }

        private StyleType CreateChartAxisYStyle()
        {
            return new StyleType();
        }

        private MajorGridLinesType CreateChartAxisYMajorGridLines()
        {
            return new MajorGridLinesType();
        }

        private MinorGridLinesType CreateChartAxisYMinorGridLines()
        {
            return new MinorGridLinesType();
        }

        private AxisTypeMajorTickMarks CreateChartAxisYMajorTickMarks()
        {
            return AxisTypeMajorTickMarks.Outside;
        }
        #endregion
    }
}
